package cn.iocoder.yudao.module.lowcode.controller.admin.table;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.lowcode.controller.admin.datasource.vo.LowcodeTableInfoRespVO;
import cn.iocoder.yudao.module.lowcode.service.datasource.LowcodeDataSourceConfigService;
import cn.iocoder.yudao.module.lowcode.service.generic.GenericTableServiceEnhancer;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

/**
 * 批量同步 Magic API 接口控制器
 * 用于为已存在的表批量生成 Magic API 接口
 *
 * @author 芋道源码
 */
@Tag(name = "低代码 - 批量同步")
@RestController
@RequestMapping("/lowcode/batch-sync")
@Validated
@Slf4j
public class BatchSyncController {

    @Resource
    private LowcodeDataSourceConfigService dataSourceConfigService;

    @Resource
    private GenericTableServiceEnhancer tableServiceEnhancer;

    @PostMapping("/sync-all-tables")
    @Operation(summary = "为数据源中所有表批量生成 Magic API 接口")
    @Parameter(name = "dataSourceId", description = "数据源ID", required = true)
    @PreAuthorize("@ss.hasPermission('lowcode:table:sync')")
    public CommonResult<Map<String, Object>> syncAllTables(@RequestParam("dataSourceId") Long dataSourceId) {
        log.info("[syncAllTables] 开始为数据源 {} 中的所有表生成 Magic API 接口", dataSourceId);
        
        try {
            // 1. 获取数据源中的所有表
            List<LowcodeTableInfoRespVO> tables = dataSourceConfigService.getTableInfoList(dataSourceId, null);
            
            if (tables == null || tables.isEmpty()) {
                log.info("[syncAllTables] 数据源 {} 中没有找到表", dataSourceId);
                return success(createResult(0, 0, 0));
            }
            
            // 2. 为每个表生成 Magic API 接口
            int totalCount = tables.size();
            int successCount = 0;
            int errorCount = 0;
            
            for (LowcodeTableInfoRespVO table : tables) {
                try {
                    log.debug("[syncAllTables] 正在为表 {} 生成 Magic API 接口", table.getName());
                    
                    tableServiceEnhancer.notifyTableCreated(
                        table.getName(),
                        dataSourceId,
                        table.getComment()
                    );
                    
                    successCount++;
                    log.debug("[syncAllTables] 表 {} 的 Magic API 接口生成成功", table.getName());
                    
                } catch (Exception e) {
                    errorCount++;
                    log.error("[syncAllTables] 为表 {} 生成 Magic API 接口失败", table.getName(), e);
                }
            }
            
            Map<String, Object> result = createResult(totalCount, successCount, errorCount);
            log.info("[syncAllTables] 批量同步完成: {}", result);
            
            return success(result);
            
        } catch (Exception e) {
            log.error("[syncAllTables] 批量同步数据源 {} 失败", dataSourceId, e);
            throw new RuntimeException("批量同步失败: " + e.getMessage(), e);
        }
    }

    @PostMapping("/sync-specific-tables")
    @Operation(summary = "为指定的表批量生成 Magic API 接口")
    @PreAuthorize("@ss.hasPermission('lowcode:table:sync')")
    public CommonResult<Map<String, Object>> syncSpecificTables(@RequestBody SyncSpecificTablesRequest request) {
        log.info("[syncSpecificTables] 开始为指定表生成 Magic API 接口，表数量: {}", request.getTableNames().size());
        
        try {
            int totalCount = request.getTableNames().size();
            int successCount = 0;
            int errorCount = 0;
            
            for (String tableName : request.getTableNames()) {
                try {
                    // 获取表注释
                    String tableComment = getTableComment(tableName, request.getDataSourceId());
                    
                    log.debug("[syncSpecificTables] 正在为表 {} 生成 Magic API 接口", tableName);
                    
                    tableServiceEnhancer.notifyTableCreated(
                        tableName,
                        request.getDataSourceId(),
                        tableComment
                    );
                    
                    successCount++;
                    log.debug("[syncSpecificTables] 表 {} 的 Magic API 接口生成成功", tableName);
                    
                } catch (Exception e) {
                    errorCount++;
                    log.error("[syncSpecificTables] 为表 {} 生成 Magic API 接口失败", tableName, e);
                }
            }
            
            Map<String, Object> result = createResult(totalCount, successCount, errorCount);
            log.info("[syncSpecificTables] 批量同步完成: {}", result);
            
            return success(result);
            
        } catch (Exception e) {
            log.error("[syncSpecificTables] 批量同步指定表失败", e);
            throw new RuntimeException("批量同步失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取表注释
     */
    private String getTableComment(String tableName, Long dataSourceId) {
        try {
            List<LowcodeTableInfoRespVO> tables = dataSourceConfigService.getTableInfoList(dataSourceId, tableName);
            return tables.stream()
                    .filter(table -> tableName.equals(table.getName()))
                    .findFirst()
                    .map(table -> table.getComment() != null ? table.getComment() : tableName)
                    .orElse(tableName);
        } catch (Exception e) {
            log.warn("[getTableComment] 获取表 {} 注释失败，使用表名", tableName);
            return tableName;
        }
    }

    /**
     * 创建结果对象
     */
    private Map<String, Object> createResult(int totalCount, int successCount, int errorCount) {
        Map<String, Object> result = new HashMap<>();
        result.put("totalCount", totalCount);
        result.put("successCount", successCount);
        result.put("errorCount", errorCount);
        result.put("message", String.format("总计 %d 个表，成功 %d 个，失败 %d 个", totalCount, successCount, errorCount));
        return result;
    }

    /**
     * 指定表同步请求
     */
    public static class SyncSpecificTablesRequest {
        private List<String> tableNames;
        private Long dataSourceId;

        public List<String> getTableNames() {
            return tableNames;
        }

        public void setTableNames(List<String> tableNames) {
            this.tableNames = tableNames;
        }

        public Long getDataSourceId() {
            return dataSourceId;
        }

        public void setDataSourceId(Long dataSourceId) {
            this.dataSourceId = dataSourceId;
        }
    }
}